package com.pzhu.acargid.doc;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pzhu.acargid.award.AwardService;
import com.pzhu.acargid.book.BookService;
import com.pzhu.acargid.certificate.CertificateService;
import com.pzhu.acargid.coauthor.CoauthorService;
import com.pzhu.acargid.domain.*;
import com.pzhu.acargid.govresearch.GovresearchService;
import com.pzhu.acargid.institution.InstitutionService;
import com.pzhu.acargid.material.MaterialService;
import com.pzhu.acargid.model.ModelService;
import com.pzhu.acargid.others.OthersService;
import com.pzhu.acargid.paper.PaperService;
import com.pzhu.acargid.patent.PatentService;
import com.pzhu.acargid.recycled.RecycledService;
import com.pzhu.acargid.report.ReportService;
import com.pzhu.acargid.research.ResearchService;
import com.pzhu.acargid.software.SoftwareService;
import com.pzhu.acargid.stuaward.StuawardService;
import com.pzhu.acargid.until.Data;
import com.pzhu.acargid.until.Filters;
import com.pzhu.acargid.until.Query;
import com.pzhu.acargid.until.Result;
import com.pzhu.acargid.vo.VO;
import com.pzhu.file.utils.FileUtil;
import com.pzhu.security.token.JwtTokenService;
import org.apache.commons.io.FileUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/doc")
public class DocController {
    @Autowired
    private DocService docService;
    @Autowired
    private PaperService paperService;
    @Autowired
    private PatentService patentService;
    @Autowired
    private SoftwareService softwareService;
    @Autowired
    private AwardService awardService;
    @Autowired
    private StuawardService stuawardService;
    @Autowired
    private MaterialService materialService;
    @Autowired
    private BookService bookService;
    @Autowired
    private ReportService reportService;
    @Autowired
    private CertificateService certificateService;
    @Autowired
    private OthersService othersService;
    @Autowired
    private RecycledService recycledService;
    @Autowired
    private ModelService modelService;
    @Autowired
    private GovresearchService govresearchService;
    @Autowired
    private ResearchService researchService;
    @Autowired
    private CoauthorService coauthorService;
    @Autowired
    private InstitutionService institutionService;

    @GetMapping
    public Result getDocPage(HttpServletRequest request, Integer page, Integer size, @RequestParam("doc_status") Integer docStatus, String model, @RequestParam("view_order") String viewOrder) {
        Integer userid = JwtTokenService.getClaim(request, "userid").asInt();
        String[] split = viewOrder.split(":");
        String view = split[0];
        String order = split[1];
        IPage iPage = new Page(page, size);
        IPage<?> paperPage = null;
        LambdaQueryWrapper<Model> modelLambdaQueryWrapper = new LambdaQueryWrapper<>();
        modelLambdaQueryWrapper.eq(Model::getModDbTable, model);
        Model oneModel = modelService.getOne(modelLambdaQueryWrapper);
        switch (model) {
            case "paper":
                paperPage = paperService.getPaperPage(userid, iPage, docStatus, model, view, order);
                break;
            case "patent":
                paperPage = patentService.getPatentPage(userid, iPage, docStatus, model, view, order);
                break;
            case "software":
                paperPage = softwareService.getSoftwarePage(userid, iPage, docStatus, model, view, order);
                break;
            case "award":
                paperPage = awardService.getAwardPage(userid, iPage, docStatus, model, view, order);
                break;
            case "stuaward":
                paperPage = stuawardService.getStuawardPage(userid, iPage, docStatus, model, view, order);
                break;
            case "material":
                paperPage = materialService.getMaterialPage(userid, iPage, docStatus, model, view, order);
                break;
            case "book":
                paperPage = bookService.getBookPage(userid, iPage, docStatus, model, view, order);
                break;
            case "report":
                paperPage = reportService.getReportPage(userid, iPage, docStatus, model, view, order);
                break;
            case "certificate":
                paperPage = certificateService.getCertificatePage(userid, iPage, docStatus, model, view, order);
                break;
            case "others":
                paperPage = othersService.getOthersPage(userid, iPage, docStatus, model, view, order);
                break;
            case "govresearch":
                paperPage = govresearchService.getGovresearchPage(userid, iPage, docStatus, model, view, order);
                break;
            case "research":
                paperPage = researchService.getResearchPage(userid, iPage, docStatus, model, view, order);
                break;
            case "recycled": {
                LambdaQueryWrapper<Recycled> recycledLambdaQueryWrapper = new LambdaQueryWrapper<>();
                recycledLambdaQueryWrapper.eq(Recycled::getUserId, userid);
                paperPage = recycledService.page(iPage, recycledLambdaQueryWrapper);
                return new Result(1, new Data(paperPage, 1, oneModel, 1), "操作成功");
            }
        }
        List<Doc> records = (List<Doc>) paperPage.getRecords();
        associationQueries(records);

        return new Result(1, new Data(paperPage, 1, oneModel, 1), "操作成功");
    }

    private void associationQueries(List<Doc> records) {

        List<Integer> collect = records.stream().map(Doc::getId).collect(Collectors.toList());
        //coauthorList
        LambdaQueryWrapper<Coauthor> coauthorLambdaQueryWrapper = new LambdaQueryWrapper<>();
        coauthorLambdaQueryWrapper.in(!collect.isEmpty(), Coauthor::getDocId, collect);
        List<Coauthor> coauthorList = coauthorService.list(coauthorLambdaQueryWrapper);
        List<Integer> integers = coauthorList.stream().map(Coauthor::getId).collect(Collectors.toList());
        //institutionList
        LambdaQueryWrapper<Institution> institutionLambdaQueryWrapper = new LambdaQueryWrapper<>();
        institutionLambdaQueryWrapper.in(!integers.isEmpty(), Institution::getAuthorId, integers);
//        List<Institution> institutionList = institutionService.list(institutionLambdaQueryWrapper);
//        Map<Integer, List<Institution>> integerListMap = institutionList.stream().collect(Collectors.groupingBy(Institution::getAuthorId));
//        coauthorList.forEach(coauthor -> coauthor.setInstitutions(integerListMap.get(coauthor.getId())));
        Map<Integer, List<Coauthor>> collected = coauthorList.stream().collect(Collectors.groupingBy(Coauthor::getDocId));
        records.forEach(doc -> doc.setCoauthors(collected.get(doc.getId())));
    }

    @PostMapping("/query")
    public Result<List<Doc>> query(HttpServletRequest request, @RequestBody Query query) {
        Integer userid = JwtTokenService.getClaim(request, "userid").asInt();
        String type = query.getType();
        Filters filters = query.getFilters();
        List<?> paperPage = null;
        switch (type) {
            case "paper":
                paperPage = paperService.filter(userid, type, filters);
                break;
            case "patent":
                paperPage = patentService.filter(userid, type, filters);
                break;
            case "software":
                paperPage = softwareService.filter(userid, type, filters);
                break;
            case "award":
                paperPage = awardService.filter(userid, type, filters);
                break;
            case "stuaward":
                paperPage = stuawardService.filter(userid, type, filters);
                break;
            case "material":
                paperPage = materialService.filter(userid, type, filters);
                break;
            case "book":
                paperPage = bookService.filter(userid, type, filters);
                break;
            case "report":
                paperPage = reportService.filter(userid, type, filters);
                break;
            case "certificate":
                paperPage = certificateService.filter(userid, type, filters);
                break;
            case "others":
                paperPage = othersService.filter(userid, type, filters);
                break;
            case "govresearch":
                paperPage = govresearchService.filter(userid, type, filters);
                break;
            case "research":
                paperPage = researchService.filter(userid, type, filters);
                break;
        }
        associationQueries((List<Doc>) paperPage);
        return new Result<>(1, (List<Doc>) paperPage, "操作成功");
    }

    @PostMapping("/remove")
    public Result remove(HttpServletRequest request, @RequestBody List<Integer> ids) {
        Integer userid = JwtTokenService.getClaim(request, "userid").asInt();
        if (ids != null && !ids.isEmpty()) {
            List<Doc> docs = docService.listByIds(ids);
            List<Recycled> collect = new ArrayList<>();
            docs.forEach(item -> {
                if (docService.removeById(item)) {
                    Recycled recycled = new Recycled();
                    recycled.setUserId(userid);
                    recycled.setDocId(item.getId());
                    recycled.setTitle(item.getTitle());
                    recycled.setRemoved(0);
                    collect.add(recycled);
                }
            });
            recycledService.saveBatch(collect);
            return new Result(1, null, "操作成功");
        }
        return new Result(0, null, "操作失败");
    }

    @GetMapping("/download")
    public ResponseEntity<byte[]> download(HttpServletRequest request, HttpServletResponse response, @RequestParam("id") String docid, String type, String title) throws IOException {
        Integer userid = JwtTokenService.getClaim(request, "userid").asInt();
        String savePath = FileUtil.getSavePath(userid, type) + docid + File.separator + title + ".pdf";
        File file = new File(savePath);
        //创建字节数组
        byte[] bytes = FileUtils.readFileToByteArray(file);

        //创建HttpHeaders对象设置响应头信息
        HttpHeaders httpHeaders = new HttpHeaders();//创建HttpHeaders对象设置响应头信息
        //设置要下载方式以及下载文件的名字
//        httpHeaders.add("Content-Disposition", "attachment;filename=aa.pdf" );//设置要下载方式以及下载文件的名字
        //设置响应状态码
        HttpStatus code = HttpStatus.OK;  //设置响应状态码
        //创建ResponseEntity对象

        return new ResponseEntity<>(bytes, httpHeaders, code);
    }

    @GetMapping("/search")
    public List<Doc> headers(String condition) {
        LambdaQueryWrapper<Doc> docLambdaQueryWrapper = new LambdaQueryWrapper<>();
        LambdaQueryWrapper<Doc> like = docLambdaQueryWrapper.like(Doc::getTitle, condition);
        return docService.list(like);
//        return Result.success(list);
    }

    @GetMapping("/getbyid")
    public VO getbyid(HttpServletRequest request, String id, String model) {
        Integer userid = JwtTokenService.getClaim(request, "userid").asInt();
        System.out.println(docService.getbyid(userid, id, model));
        return docService.getbyid(userid, id, model);
    }

}